home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d3 / ddjhptxt.arc / KING.LST < prev    next >
File List  |  1990-06-05  |  12KB  |  487 lines

  1. LISTING ONE
  2.  
  3. /*-----------------------------------------
  4.   Demonstrates basic principles of hypertext
  5.   document construction and management.
  6.   (c) Copyright 1989 Todd King
  7.          All Rights Reserved
  8.   Written: Todd King
  9. -------------------------------------------*/
  10.  
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <conio.h>
  14. #include <ctype.h>
  15. #include "hyper_d.h"
  16.  
  17. main()
  18. {
  19.   int n;
  20.  
  21.   clrscr();
  22.   printf("(c) Copyright 1989 Todd King. All Rights Reserved\n");
  23.   sleep(2);
  24.  
  25.   if((Hyper_fptr = fopen("HYPER.TXT", "r")) == NULL)
  26.   {
  27.     perror("fopen");
  28.     exit(1);
  29.   }
  30.  
  31.   build_hyperbase();
  32.  
  33.   n = 0;
  34.   while((n = enter_text(Hyperbase[n].tag)) != -1) ;
  35.  
  36.   clrscr();
  37.   fclose(Hyper_fptr);
  38. }
  39.  
  40. /*-----------------------------------------
  41.   Builds the global index data base for the
  42.   hypertext document.
  43.   Written: Todd King
  44. -------------------------------------------*/
  45. build_hyperbase()
  46. {
  47.   char buffer[MAX_HYPER_LINE];
  48.   HYPERITEM *hitem;
  49.    int n;
  50.  
  51.   for(;;)
  52.   {
  53.     if(fgets(buffer, sizeof(buffer), Hyper_fptr) == NULL)
  54.     {
  55.       break;
  56.     }
  57.     switch(buffer[0])
  58.     {
  59.       case '\f':
  60.         if((hitem = make_item()) == NULL)
  61.         {
  62.           fprintf(stderr, "No more room in the Hyperbase\n");
  63.           exit(0);
  64.         }
  65.         fgets(buffer, sizeof(buffer), Hyper_fptr);
  66.         n = strlen(buffer);
  67.         if(buffer[n - 1] == '\n') buffer[n - 1] = '\0';
  68.         set_tag(hitem, buffer);
  69.         set_position(hitem, ftell(Hyper_fptr));
  70.         break;
  71.     }
  72.   }
  73.   return(Hyper_cnt);
  74. }
  75.  
  76. /*-----------------------------------------
  77.   Enters the hypertext document at a specific
  78.   tag location. It then allows navigation within
  79.   the document.
  80.   Written: Todd King
  81. -------------------------------------------*/
  82. enter_text(tag)
  83. char tag[];
  84. {
  85.   int c, n;
  86.   HYPERITEM *hitem;
  87.   char *bptr;
  88.   char *pptr;
  89.   char *tptr;
  90.   int i;
  91.   char buffer[MAX_HYPER_LINE];
  92.   int line_put;
  93.   int line_cnt = 3;
  94.   int col_cnt = 0;
  95.   int ref_cnt = 0;
  96.   int hidx;
  97.   HYPER_REF hyper_ref[MAX_HYPER];
  98.  
  99.   hitem = find_item(tag);
  100.   if(hitem == NULL)
  101.   {
  102.      fprintf(stderr,
  103.       "No hypertext subject by the name of '%s' exists\n", tag);
  104.     return(-1);
  105.   }
  106.   hidx = hyper_idx(tag);
  107.   clrscr();
  108.   fseek(Hyper_fptr, hitem->position, SEEK_SET);
  109.   bptr = fgets(buffer, sizeof(buffer), Hyper_fptr);
  110.   textcolor(LIGHTGRAY);
  111.   gotoxy(1,24);
  112.   cputs("ESCAPE: to exit; UP ARROW, DOWN ARROW: to navigate");
  113.   gotoxy(1,1);
  114.   cputs(tag); cputs("\r\n"); cputs("\r\n");
  115.   while(bptr != NULL)   /* For all lines in the current hypercard */
  116.   {
  117.     col_cnt = 1;
  118.     for(i = 0; i < Hyper_cnt; i++)
  119.     {
  120.      if((pptr = strstr(bptr, Hyperbase[i].tag)) != NULL)
  121.      {
  122.        if( i == hidx) continue; /* no self-referencing */
  123.        if(pptr != bptr)
  124.        {
  125.          if(!ispunct(*(pptr - 1)) && !isspace(*(pptr - 1))) continue;
  126.        }
  127.        tptr = pptr + strlen(Hyperbase[i].tag);
  128.        if(ispunct(*tptr) || isspace(*tptr) || *tptr == '\0')
  129.        {
  130.          /* Deliniator */
  131.        } else {         /* No good */
  132.          continue;
  133.        }
  134.  /* If we reach here we've found a genuine tag */
  135.         pptr[0] ='\0';
  136.         col_cnt += strlen(bptr);
  137.         hyper_ref[ref_cnt].line = line_cnt;
  138.         hyper_ref[ref_cnt].column = col_cnt;
  139.         hyper_ref[ref_cnt].tag = Hyperbase[i].tag;
  140.         cputs(bptr);
  141.         textcolor(YELLOW);
  142.         cputs(Hyperbase[i].tag);
  143.         textcolor(LIGHTGRAY);
  144.         bptr = pptr + strlen(Hyperbase[i].tag);
  145.         col_cnt += strlen(Hyperbase[i].tag);
  146.         ref_cnt++;
  147.       }
  148.     }
  149.     cputs(bptr);
  150.     cprintf("\r");
  151.     if(line_cnt >= 23) {  /* What to do at the end of a screen */
  152.        break;
  153.     }
  154.     bptr = fgets(buffer, sizeof(buffer), Hyper_fptr);
  155.     if(buffer[0] == '\f') bptr = NULL;
  156.     line_cnt++;
  157.     col_cnt = 0;
  158.   }
  159.   if((n = nav_ref(hyper_ref, ref_cnt)) >= 0) return(n);
  160.  
  161. }
  162. /*-----------------------------------------
  163.   The function that performs the actual
  164.   navigation within a hypertext document.
  165.   Written: Todd King
  166. -------------------------------------------*/
  167. nav_ref(hyper_ptr, max_ref)
  168. HYPER_REF hyper_ptr[];
  169. int max_ref;
  170. {
  171.   int advance = 0;
  172.   int selected = -1;
  173.   int cur_ref = 0;
  174.  
  175.   for(;;)
  176.   {
  177.     cur_ref += advance;
  178.     if(cur_ref < 0) cur_ref = max_ref - 1;
  179.     if(cur_ref >= max_ref) cur_ref = 0;
  180.     advance = 0;
  181.     gotoxy(hyper_ptr[cur_ref].column, hyper_ptr[cur_ref].line);
  182.     textbackground(LIGHTGRAY);
  183.     textcolor(BLACK);
  184.     cputs(hyper_ptr[cur_ref].tag);
  185.     switch(getch())
  186.     {
  187.       case 0:
  188.         switch(getch())
  189.         {
  190.           case DOWN_ARROW:
  191.             advance = 1;
  192.             break;
  193.           case UP_ARROW:
  194.             advance = -1;
  195.             break;
  196.         }
  197.         break;
  198.       case '\r':
  199.       case '\n':
  200.         selected = cur_ref;
  201.         break;
  202.        case ESC:
  203.         textbackground(BLACK);
  204.         textcolor(LIGHTGRAY);
  205.         return(-1);
  206.     }
  207.     gotoxy(hyper_ptr[cur_ref].column, hyper_ptr[cur_ref].line);
  208.     textcolor(YELLOW);
  209.     textbackground(BLACK);
  210.     cputs(hyper_ptr[cur_ref].tag);
  211.     if(selected != -1) return(hyper_idx(hyper_ptr[selected].tag));
  212.   }
  213. }
  214.  
  215. /*-----------------------------------------
  216.   Determines the index of a hypertext tag
  217.   within the global database.
  218.   Written: Todd King
  219. -------------------------------------------*/
  220. hyper_idx(tag_str)
  221. char tag_str[];
  222. {
  223.   int i;
  224.   for(i = 0; i < Hyper_cnt; i++) {
  225.     if(strcmp(tag_str, Hyperbase[i].tag) == 0) return(i);
  226.   }
  227.   return(-1);
  228. }
  229.  
  230. /*-----------------------------------------
  231.   Locates an item in the global database
  232.   with the tag as a key. Returns a pointer
  233.   to the entry or NULL if one does not exist.
  234.   Written: Todd King
  235. -------------------------------------------*/
  236. HYPERITEM *find_item(tag)
  237. char tag[];
  238. {
  239.   HYPERITEM *hitem;
  240.   int i;
  241.  
  242.   for(i = 0; i < Hyper_cnt; i++)
  243.   {
  244.     hitem = &Hyperbase[i];
  245.     if(strcmp(tag, hitem->tag) == 0) return(hitem);
  246.   }
  247.   return(NULL);
  248. }
  249.  
  250. /*-----------------------------------------
  251.   Sets the tag portion of a database entry to
  252.   the contents in a passed string
  253.   Written: Todd King
  254. -------------------------------------------*/
  255. set_tag(hitem, buffer)
  256. HYPERITEM *hitem;
  257. char buffer[];
  258. {
  259.   char *malloc();
  260.  
  261.   hitem->tag = malloc(strlen(buffer) + 1);
  262.   if(hitem->tag == NULL)
  263.   {
  264.     perror("malloc");
  265.     exit(2);
  266.   }
  267.   strcpy(hitem->tag, buffer);
  268. }
  269. /*-----------------------------------------
  270.   Makes (extracts) a new database entry item
  271.   from the item pool.
  272.   Written: Todd King
  273. -------------------------------------------*/
  274. HYPERITEM *make_item()
  275. {
  276.   if(Hyper_cnt >= MAX_HYPER) return(NULL);
  277.   return(&Hyperbase[Hyper_cnt++]);
  278. }
  279.  
  280.  
  281. LISTING TWO
  282.  
  283. #define UP_ARROW        72
  284. #define DOWN_ARROW      80
  285. #define ESC             27
  286.  
  287. typedef struct {
  288.   char *tag;
  289.   int position;
  290. } HYPERITEM;
  291.  
  292. typedef struct {
  293.     int line;
  294.     int column;
  295.     char *tag;
  296.   } HYPER_REF;
  297.  
  298. #define MAX_HYPER       1024
  299. HYPERITEM Hyperbase[MAX_HYPER];
  300. int Hyper_cnt = 0;
  301.  
  302. FILE *Hyper_fptr;
  303.  
  304. HYPERITEM *make_item();
  305. HYPERITEM *find_item();
  306. #define set_position(h, p)  h->position = p
  307.  
  308. #define TRUE    1
  309. #define FALSE   0
  310.  
  311. #define MAX_HYPER_LINE  80
  312.  
  313.  
  314. LISTING THREE
  315.  
  316. .................................................................
  317. Function Flow Diagram
  318.  
  319.  main()       build_hyperbase()             make_item()
  320.  
  321.                                              set_tag()
  322.  
  323.                                           set_position()
  324.                  enter_text()              find_item()
  325.  
  326.                                           hyper_idx()
  327.  
  328.                                             nav_ref()
  329. .................................................................
  330. main()
  331.  
  332. This is an application that displays a hypertext document.
  333. It automatically creates a list of hyper-items (or cards)
  334. that are in the hypertext document. Then it creates the
  335. appropriate links so that you can navigate to any item
  336. that is referenced by any other item. It uses the contents
  337. of the file "HYPER.TXT" as the hypertext document and begins
  338. at the first item in the document.
  339.  
  340.  
  341. Function Flow Diagram
  342. .................................................................
  343. build_hyperbase()
  344.  
  345. build_hyperbase()
  346.  
  347. This function builds the global database for the hypertext
  348. document. It scans the entire document and assembles a list
  349. of all cards in the document and stores their location
  350. within the file and the tag, which the card is to be known
  351. by. This database is stored in the global variable
  352. "Hyperbase".
  353.  
  354.  
  355. Function Flow Diagram
  356. .................................................................
  357. enter_text()
  358.  
  359. enter_text(tag)
  360. char tag[];
  361.  
  362. Enters the hypertext document at a specific
  363. tag location. The tag (a string) is passed in the variable
  364. first variable called "tag". It then allows navigation
  365. within the document.
  366.  
  367.  
  368. Function Flow Diagram
  369. .................................................................
  370. nav_ref()
  371.  
  372. nav_ref(cur_ref, hyper_ptr, max_ref)
  373. int cur_ref;
  374. HYPER_REF hyper_ptr[];
  375. int max_ref;
  376.  
  377. This function performs the actual navigation within a
  378. single card. It returns the index of the hyper-item within
  379. the card which was selected. A special code (-1) is returned
  380. if a request to exit is entered. "cur_ref" is the index of
  381. the current card, "hyper_ptr" is a pointer to a structure
  382. containing the list of references in the card and "max_ref
  383. is the number of references in "hyper_ptr".
  384.  
  385.  
  386. Function Flow Diagram
  387. .................................................................
  388. hyper_idx()
  389.  
  390. hyper_idx(tag_str)
  391. char tag_str();
  392.  
  393. Returns the index of the tag "tag_str". The global
  394. database ("Hyperbase") is searched for the existence of
  395. the tag.
  396.  
  397.  
  398. Function Flow Diagram
  399. .................................................................
  400. find_item()
  401.  
  402. HYPERITEM *find_item(tag)
  403. char tag[];
  404.  
  405. Locates an item in the global database ("Hyperbase")
  406. with the tag as a key. Returns a pointer
  407. to the entry or NULL if one does not exist.
  408.  
  409.  
  410. Function Flow Diagram
  411. .................................................................
  412. set_tag()
  413.  
  414. set_tag(hitem, buffer)
  415. HYPERITEM *hitem;
  416. char buffer[];
  417.  
  418. Sets the tag portion of the database entry pointed
  419. to by "hitem" to the contents in the string "buffer".
  420.  
  421.  
  422. Function Flow Diagram
  423. .................................................................
  424. make_item()
  425.  
  426. HYPERITEM *make_item()
  427.  
  428. Makes a new database entry. Actually it extracts
  429. the next available entry for a pool and returns a pointer
  430. to the entry.
  431.  
  432. Function Flow Diagram
  433. .................................................................
  434. set_position()
  435.  
  436. set_position(h, p)
  437. HYPERITEM *h;
  438. int p;
  439.  
  440. Actually a psuedofunction (created with a define) which
  441. assigns an location of an item in a file to the item
  442. definition.
  443.  
  444.  
  445. Function Flow Diagram
  446. .................................................................
  447. HYPERITEM
  448.  
  449. A structure that contains a complete description a single
  450. item (or card) with the hypertext document. It is of the
  451. form:
  452.  
  453. typedef struct {
  454.   char *tag;
  455.   int position;
  456. } HYPERITEM;
  457.  
  458.  
  459. Function Flow Diagram
  460. .................................................................
  461. HYPER_REF
  462.  
  463. A structure of the form:
  464.  
  465. typedef struct {
  466.     int line;
  467.     int column;
  468.     char *tag;
  469.   } HYPER_REF;
  470.  
  471.  
  472. Function Flow Diagram
  473. .................................................................
  474. HYPER.TXT
  475.  
  476. The text file that contains the hypertext document. The
  477. beginning of an item is marked by a special line. This line
  478. is a formfeed followed by a newline. The next line after
  479. this is considerd to be the name of the item (the item tag).
  480. If this name appears in any other tag then navigation to
  481. the item is allowed by selecting the tag in the item.
  482.  
  483.  
  484. Function Flow Diagram
  485.  
  486.  
  487.